//! # 可配置组件抽象
//!
//! 定义通用的 ConfigurableComponent trait，为所有需要配置管理的组件提供统一接口

use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::any::Any;

use crate::error::{ConfigCenterResult, ConfigCenterError};

/// 配置组件通用接口
/// 
/// 所有需要配置管理的组件都应该实现这个 trait
#[async_trait]
pub trait ConfigurableComponent: Send + Sync {
    /// 组件名称
    fn component_name(&self) -> &str;
    
    /// 组件版本
    fn component_version(&self) -> &str;
    
    /// 获取组件当前配置
    async fn get_config(&self) -> ConfigCenterResult<Box<dyn ConfigValue>>;
    
    /// 更新组件配置
    async fn update_config(&mut self, config: Box<dyn ConfigValue>) -> ConfigCenterResult<()>;
    
    /// 验证配置有效性
    async fn validate_config(&self, config: &dyn ConfigValue) -> ConfigCenterResult<ValidationResult>;
    
    /// 配置更新前的回调
    async fn before_config_update(&mut self, old_config: &dyn ConfigValue, new_config: &dyn ConfigValue) -> ConfigCenterResult<()> {
        // 默认实现：什么都不做
        let _ = (old_config, new_config);
        Ok(())
    }
    
    /// 配置更新后的回调
    async fn after_config_update(&mut self, old_config: &dyn ConfigValue, new_config: &dyn ConfigValue) -> ConfigCenterResult<()> {
        // 默认实现：什么都不做
        let _ = (old_config, new_config);
        Ok(())
    }
    
    /// 获取配置模式（用于验证）
    fn get_config_schema(&self) -> ConfigSchema;
    
    /// 是否支持热更新
    fn supports_hot_reload(&self) -> bool {
        true
    }
}

/// 配置值抽象接口
pub trait ConfigValue: Send + Sync {
    /// 转换为 JSON 值
    fn as_json(&self) -> ConfigCenterResult<serde_json::Value>;
    
    /// 从 JSON 值创建
    fn from_json(value: serde_json::Value) -> ConfigCenterResult<Box<dyn ConfigValue>>
    where
        Self: Sized;
    
    /// 获取配置类型名称
    fn type_name(&self) -> &'static str;
    
    /// 克隆配置值
    fn clone_box(&self) -> Box<dyn ConfigValue>;
    
    /// 转换为 Any 类型（用于向下转型）
    fn as_any(&self) -> &dyn Any;
}

/// 通用配置值实现
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GenericConfigValue {
    pub value: serde_json::Value,
    pub type_name: String,
}

impl ConfigValue for GenericConfigValue {
    fn as_json(&self) -> ConfigCenterResult<serde_json::Value> {
        Ok(self.value.clone())
    }
    
    fn from_json(value: serde_json::Value) -> ConfigCenterResult<Box<dyn ConfigValue>> {
        Ok(Box::new(GenericConfigValue {
            type_name: "generic".to_string(),
            value,
        }))
    }
    
    fn type_name(&self) -> &'static str {
        "generic"
    }
    
    fn clone_box(&self) -> Box<dyn ConfigValue> {
        Box::new(self.clone())
    }
    
    fn as_any(&self) -> &dyn Any {
        self
    }
}

/// 配置验证结果
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationResult {
    /// 是否有效
    pub is_valid: bool,
    /// 错误列表
    pub errors: Vec<ValidationError>,
    /// 警告列表
    pub warnings: Vec<ValidationWarning>,
}

/// 配置验证错误
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationError {
    /// 字段路径
    pub field_path: String,
    /// 错误消息
    pub message: String,
    /// 错误代码
    pub error_code: String,
}

/// 配置验证警告
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationWarning {
    /// 字段路径
    pub field_path: String,
    /// 警告消息
    pub message: String,
    /// 警告代码
    pub warning_code: String,
}

/// 配置模式定义
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigSchema {
    /// 模式名称
    pub name: String,
    /// 版本
    pub version: String,
    /// 字段定义
    pub fields: HashMap<String, FieldSchema>,
    /// 是否允许额外字段
    pub allow_additional_fields: bool,
}

/// 字段模式定义
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldSchema {
    /// 字段类型
    pub field_type: FieldType,
    /// 是否必需
    pub required: bool,
    /// 默认值
    pub default_value: Option<serde_json::Value>,
    /// 描述
    pub description: String,
    /// 验证规则
    pub validation_rules: Vec<ValidationRule>,
}

/// 字段类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FieldType {
    String,
    Integer,
    Float,
    Boolean,
    Array(Box<FieldType>),
    Object(HashMap<String, FieldSchema>),
    Enum(Vec<String>),
}

/// 验证规则
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ValidationRule {
    /// 最小值（数字）
    MinValue(f64),
    /// 最大值（数字）
    MaxValue(f64),
    /// 最小长度（字符串/数组）
    MinLength(usize),
    /// 最大长度（字符串/数组）
    MaxLength(usize),
    /// 正则表达式（字符串）
    Pattern(String),
    /// 枚举值
    OneOf(Vec<serde_json::Value>),
    /// 自定义验证函数名
    CustomValidator(String),
}

impl ValidationResult {
    /// 创建成功的验证结果
    pub fn success() -> Self {
        Self {
            is_valid: true,
            errors: Vec::new(),
            warnings: Vec::new(),
        }
    }
    
    /// 创建失败的验证结果
    pub fn failure(errors: Vec<ValidationError>) -> Self {
        Self {
            is_valid: false,
            errors,
            warnings: Vec::new(),
        }
    }
    
    /// 添加错误
    pub fn add_error(&mut self, field_path: String, message: String, error_code: String) {
        self.errors.push(ValidationError {
            field_path,
            message,
            error_code,
        });
        self.is_valid = false;
    }
    
    /// 添加警告
    pub fn add_warning(&mut self, field_path: String, message: String, warning_code: String) {
        self.warnings.push(ValidationWarning {
            field_path,
            message,
            warning_code,
        });
    }
}

/// 配置组件管理器
pub struct ComponentManager {
    components: HashMap<String, Box<dyn ConfigurableComponent>>,
}

impl ComponentManager {
    /// 创建新的组件管理器
    pub fn new() -> Self {
        Self {
            components: HashMap::new(),
        }
    }
    
    /// 注册组件
    pub fn register_component(&mut self, component: Box<dyn ConfigurableComponent>) -> ConfigCenterResult<()> {
        let name = component.component_name().to_string();
        if self.components.contains_key(&name) {
            return Err(ConfigCenterError::ValidationError(
                format!("组件 '{}' 已经注册", name)
            ));
        }
        self.components.insert(name, component);
        Ok(())
    }
    
    /// 获取组件
    pub fn get_component(&self, name: &str) -> Option<&dyn ConfigurableComponent> {
        self.components.get(name).map(|c| c.as_ref())
    }
    
    /// 获取可变组件
    pub fn get_component_mut(&mut self, name: &str) -> Option<&mut Box<dyn ConfigurableComponent>> {
        self.components.get_mut(name)
    }
    
    /// 列出所有组件名称
    pub fn list_components(&self) -> Vec<String> {
        self.components.keys().cloned().collect()
    }
    
    /// 更新组件配置
    pub async fn update_component_config(&mut self, component_name: &str, config: Box<dyn ConfigValue>) -> ConfigCenterResult<()> {
        let component = self.components.get_mut(component_name)
            .ok_or_else(|| ConfigCenterError::NotFound(format!("组件 '{}' 未找到", component_name)))?;
        
        // 验证配置
        let validation_result = component.validate_config(config.as_ref()).await?;
        if !validation_result.is_valid {
            return Err(ConfigCenterError::ValidationError(
                format!("配置验证失败: {:?}", validation_result.errors)
            ));
        }
        
        // 获取旧配置
        let old_config = component.get_config().await?;
        
        // 调用更新前回调
        component.before_config_update(old_config.as_ref(), config.as_ref()).await?;
        
        // 更新配置
        component.update_config(config.clone_box()).await?;
        
        // 调用更新后回调
        component.after_config_update(old_config.as_ref(), config.as_ref()).await?;
        
        Ok(())
    }
    
    /// 验证所有组件配置
    pub async fn validate_all_configs(&self) -> ConfigCenterResult<HashMap<String, ValidationResult>> {
        let mut results = HashMap::new();
        
        for (name, component) in &self.components {
            let config = component.get_config().await?;
            let validation_result = component.validate_config(config.as_ref()).await?;
            results.insert(name.clone(), validation_result);
        }
        
        Ok(results)
    }
}

impl Default for ComponentManager {
    fn default() -> Self {
        Self::new()
    }
}

/// 配置验证器
pub struct ConfigValidator;

impl ConfigValidator {
    /// 根据模式验证配置
    pub fn validate_against_schema(config: &serde_json::Value, schema: &ConfigSchema) -> ValidationResult {
        let mut result = ValidationResult::success();
        
        if let serde_json::Value::Object(config_obj) = config {
            // 验证必需字段
            for (field_name, field_schema) in &schema.fields {
                if field_schema.required && !config_obj.contains_key(field_name) {
                    result.add_error(
                        field_name.clone(),
                        format!("必需字段 '{}' 缺失", field_name),
                        "REQUIRED_FIELD_MISSING".to_string(),
                    );
                }
            }
            
            // 验证字段类型和规则
            for (field_name, field_value) in config_obj {
                if let Some(field_schema) = schema.fields.get(field_name) {
                    Self::validate_field_value(field_value, field_schema, field_name, &mut result);
                } else if !schema.allow_additional_fields {
                    result.add_warning(
                        field_name.clone(),
                        format!("字段 '{}' 不在模式中定义", field_name),
                        "ADDITIONAL_FIELD".to_string(),
                    );
                }
            }
        } else {
            result.add_error(
                "root".to_string(),
                "配置必须是对象类型".to_string(),
                "INVALID_TYPE".to_string(),
            );
        }
        
        result
    }
    
    /// 验证字段值
    fn validate_field_value(
        value: &serde_json::Value,
        schema: &FieldSchema,
        field_path: &str,
        result: &mut ValidationResult,
    ) {
        // 验证字段类型
        if !Self::validate_field_type(value, &schema.field_type) {
            result.add_error(
                field_path.to_string(),
                format!("字段类型不匹配，期望: {:?}", schema.field_type),
                "TYPE_MISMATCH".to_string(),
            );
            return;
        }
        
        // 验证规则
        for rule in &schema.validation_rules {
            if let Err(error_msg) = Self::validate_rule(value, rule) {
                result.add_error(
                    field_path.to_string(),
                    error_msg,
                    "VALIDATION_RULE_FAILED".to_string(),
                );
            }
        }
    }
    
    /// 验证字段类型
    fn validate_field_type(value: &serde_json::Value, field_type: &FieldType) -> bool {
        match (value, field_type) {
            (serde_json::Value::String(_), FieldType::String) => true,
            (serde_json::Value::Number(n), FieldType::Integer) => n.is_i64(),
            (serde_json::Value::Number(_), FieldType::Float) => true,
            (serde_json::Value::Bool(_), FieldType::Boolean) => true,
            (serde_json::Value::Array(arr), FieldType::Array(element_type)) => {
                arr.iter().all(|item| Self::validate_field_type(item, element_type))
            }
            (serde_json::Value::Object(_), FieldType::Object(_)) => true,
            (serde_json::Value::String(s), FieldType::Enum(allowed_values)) => {
                allowed_values.contains(s)
            }
            _ => false,
        }
    }
    
    /// 验证规则
    fn validate_rule(value: &serde_json::Value, rule: &ValidationRule) -> Result<(), String> {
        match rule {
            ValidationRule::MinValue(min) => {
                if let Some(num) = value.as_f64() {
                    if num < *min {
                        return Err(format!("值 {} 小于最小值 {}", num, min));
                    }
                }
            }
            ValidationRule::MaxValue(max) => {
                if let Some(num) = value.as_f64() {
                    if num > *max {
                        return Err(format!("值 {} 大于最大值 {}", num, max));
                    }
                }
            }
            ValidationRule::MinLength(min_len) => {
                let len = match value {
                    serde_json::Value::String(s) => s.len(),
                    serde_json::Value::Array(arr) => arr.len(),
                    _ => return Ok(()),
                };
                if len < *min_len {
                    return Err(format!("长度 {} 小于最小长度 {}", len, min_len));
                }
            }
            ValidationRule::MaxLength(max_len) => {
                let len = match value {
                    serde_json::Value::String(s) => s.len(),
                    serde_json::Value::Array(arr) => arr.len(),
                    _ => return Ok(()),
                };
                if len > *max_len {
                    return Err(format!("长度 {} 大于最大长度 {}", len, max_len));
                }
            }
            ValidationRule::Pattern(pattern) => {
                if let Some(s) = value.as_str() {
                    let regex = regex::Regex::new(pattern)
                        .map_err(|_| "无效的正则表达式".to_string())?;
                    if !regex.is_match(s) {
                        return Err(format!("值 '{}' 不匹配模式 '{}'", s, pattern));
                    }
                }
            }
            ValidationRule::OneOf(allowed_values) => {
                if !allowed_values.contains(value) {
                    return Err(format!("值不在允许的选项中: {:?}", allowed_values));
                }
            }
            ValidationRule::CustomValidator(_validator_name) => {
                // 自定义验证器需要在具体实现中处理
                // 这里只是占位符
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_validation_result() {
        let mut result = ValidationResult::success();
        assert!(result.is_valid);
        assert_eq!(result.errors.len(), 0);
        
        result.add_error(
            "field1".to_string(),
            "错误消息".to_string(),
            "ERROR_CODE".to_string(),
        );
        assert!(!result.is_valid);
        assert_eq!(result.errors.len(), 1);
    }

    #[test]
    fn test_generic_config_value() {
        let value = serde_json::json!({"key": "value"});
        let config = GenericConfigValue {
            value: value.clone(),
            type_name: "test".to_string(),
        };
        
        assert_eq!(config.as_json().unwrap(), value);
        assert_eq!(config.type_name(), "generic");
    }
}